package com.roy.hystrix;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import com.netflix.hystrix.HystrixCollapser;
import com.netflix.hystrix.HystrixCollapser.CollapsedRequest;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixEventType;
import com.netflix.hystrix.HystrixRequestLog;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;

public class CollapserCommandMain {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		HystrixRequestContext context = HystrixRequestContext.initializeContext(); 
		Future<String> f1 = new CollapserCommand(1).queue();
		Future<String> f2 = new CollapserCommand(2).queue();
		Future<String> f3 = new CollapserCommand(3).queue();
		Future<String> f4 = new CollapserCommand(4).queue();
		Future<String> f5 = new CollapserCommand(5).queue();
		Future<String> f6 = new CollapserCommand(6).queue();
		//将六个相似的命令聚合成一个批量处理的命令一起执行，减少请求线程开销。
		System.out.println(f1.get());
		System.out.println(f2.get());
		System.out.println(f3.get());
		System.out.println(f4.get());
		System.out.println(f5.get());
		System.out.println(f6.get());
		//查看请求次数
        int count = HystrixRequestLog.getCurrentRequest().getExecutedCommands().size();  
        HystrixCommand<?> command = HystrixRequestLog.getCurrentRequest().getExecutedCommands().toArray(new HystrixCommand<?>[1])[0];
        System.out.println("request size = "+count);
        System.out.println("command name = "+command);
        //查看执行结果
        System.out.println(command.getExecutionEvents().contains(HystrixEventType.COLLAPSED));
        System.out.println(command.getExecutionEvents().contains(HystrixEventType.SUCCESS));
	}
	//请求聚合Command
	public static class CollapserCommand extends HystrixCollapser<List<String>, String, Integer> {
		private int key;
		public CollapserCommand(int key) {
			this.key = key;
		}
		//将请求聚合到一个BatchCommand。
		@Override
		protected HystrixCommand<List<String>> createCommand(Collection<CollapsedRequest<String, Integer>> requests) {
			return new BatchCommand(requests);
		}
		@Override
		public Integer getRequestArgument() {
			return key;
		}
		//将BatchCommand的输出结果匹配到各个请求上。
		@Override
		protected void mapResponseToRequests(List<String> batchResponse, Collection<CollapsedRequest<String, Integer>> requests) {
			int count = 0;
			for (CollapsedRequest<String, Integer> request : requests) {
				request.setResponse(batchResponse.get(count++));
			}
		}
	}
	//批量请求的Command
	private static class BatchCommand extends HystrixCommand<List<String>> {
		private final Collection<CollapsedRequest<String, Integer>> requests;
		protected BatchCommand(Collection<CollapsedRequest<String, Integer>> requests) {
			super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
					.andCommandKey(HystrixCommandKey.Factory.asKey("ExampleCommand")));
			this.requests = requests;
		}
		@Override
		protected List<String> run() throws Exception {
			ArrayList<String> response = new ArrayList<String>();
			for (CollapsedRequest<String, Integer> request : requests) {
				response.add("ValueForKey: " + request.getArgument());
			}
			return response;
		}
	}
}
